package com.molichuxing.gateway.bff.orders.services.impl;

import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.utils.DateUtil;
import com.molichuxing.gateway.bff.orders.convertor.Convert;
import com.molichuxing.gateway.bff.orders.entity.response.*;
import com.molichuxing.gateway.bff.orders.services.OrderBffService;
import com.molichuxing.gateway.bff.user.entity.response.UserVo;
import com.molichuxing.gateway.contants.OrderConst;
import com.molichuxing.gateway.property.OrderButtonEnum;
import com.molichuxing.gateway.utils.OrderUtil;
import com.molichuxing.services.business.dto.response.*;
import com.molichuxing.services.business.service.*;
import com.molichuxing.services.contants.OrderStatusConst;
import com.molichuxing.services.infrastructure.dto.response.*;
import com.molichuxing.services.infrastructure.service.*;
import com.molichuxing.services.property.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service("orderBffService")
public class OrderBffServiceImpl implements OrderBffService {
	private static final Logger logger = LoggerFactory.getLogger(OrderBffServiceImpl.class);

	@Resource
	private OrderBizService orderBizService;

	@Resource
	private OrderExclusivelBizService orderExclusivelBizService;

	@Resource
	private OrderSubscribeBizService orderSubscribeBizService;

	@Resource
	private OrderSubscribeService orderSubscribeService;

	@Resource
	private OrderScheduleService orderScheduleService;

	@Resource
	private OrderDeliveryService orderDeliveryService;

	@Resource
	private OrderMileageService orderMileageService;

	@Resource
	private OrderSubscribeSettlementService orderSubscribeSettlementService;

	@Resource
	private OrderPurchaseBizService orderPurchaseBizService;

	@Resource
	private OrderRenewBizService orderRenewBizService;

	@Resource
	private OrderRenegeService orderRenegeService;

	@Resource
	private OrderTradeBizService orderTradeBizService;

	@Resource
	private StoreService storeService;

	@Resource
	private StoreBizService storeBizService;

	@Resource
	private VehicleBizService vehicleBizService;

	@Resource
	private CarService carService;

	@Resource
	private CarBizService carBizService;

	@Resource
	private GoodsBizService goodsBizService;

	@Resource
	private IovCarService iovCarService;

	@Resource
	private BlacklistService blacklistService;

	@Resource
	private CheckService checkService;


	/**
	 * 查询用户的订单列表信息（mobile）
	 * 
	 * @param userId
	 *            用户id
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<OrderMobileListVo> getMobileList(Integer userId, String appVersion) throws Exception {
		List<OrderMobileListVo> result = null;
		// 获取所有用户正常订单
		List<OrderMemberBizDto> orderMemberBizDtos = orderBizService.getNormalOrderByUser(userId);
		if (orderMemberBizDtos == null || orderMemberBizDtos.isEmpty()) {
			return result;
		}
		// 门店id集合
		List<Integer> storeIds = new ArrayList<>(orderMemberBizDtos.size());
		// 车型id集合
		List<Integer> vehicleIds = new ArrayList<>(orderMemberBizDtos.size());
		for (OrderMemberBizDto orderMemberBizDto : orderMemberBizDtos) {
			if (OrderTypeEnum.EXCLUSIVEL.equals(orderMemberBizDto.getType())) {
				OrderExclusivelBizDto orderExclusivelBizDto = (OrderExclusivelBizDto) orderMemberBizDto;
				if (OrderExclusivelTypeEnum.TYPE_TWO.equals(orderExclusivelBizDto.getExclusivelType())) {
					// 专属-订悦不显示
					continue;
				}

			}
			storeIds.add(orderMemberBizDto.getPlaceStoreId());
			vehicleIds.add(orderMemberBizDto.getVehicleId());
		}
		if (storeIds.isEmpty() || vehicleIds.isEmpty()) {
			return result;
		}
		// 查询门店
		Map<Integer, StoreDto> storeMap = storeService.getStoreMapByIds(storeIds);
		// 查询车型信息
		Map<Integer, VehicleNameBizDto> vehicleMap = vehicleBizService.getCarByModelNameList(vehicleIds);

		result = new ArrayList<>(orderMemberBizDtos.size());
		for (OrderMemberBizDto orderMemberBizDto : orderMemberBizDtos) {
			if (OrderTypeEnum.EXCLUSIVEL.equals(orderMemberBizDto.getType())) {
				OrderExclusivelBizDto orderExclusivelBizDto = (OrderExclusivelBizDto) orderMemberBizDto;
				if (OrderExclusivelTypeEnum.TYPE_TWO.equals(orderExclusivelBizDto.getExclusivelType())) {
					// 专属-订悦不显示
					continue;
				}
			}
			OrderMobileListVo vo = Convert.toOrderMobileListVo(orderMemberBizDto);
			// 门店
			StoreDto storeDto = storeMap == null ? null : storeMap.get(orderMemberBizDto.getPlaceStoreId());
			// 门店名称
			vo.setStoreName(storeDto == null ? null : storeDto.getShortName());
			// 车型
			VehicleNameBizDto vehicleBizDto = vehicleMap == null ? null
					: vehicleMap.get(orderMemberBizDto.getVehicleId());
			if (vehicleBizDto != null) {
				// 商品名称（ 品牌+车系+车型名称）
				vo.setGoodsName(vehicleBizDto.getSubBrandName() + " " + vehicleBizDto.getSeriesName() + " "
						+ vehicleBizDto.getModelName());
				// 车辆图片
				vo.setCarImg(vehicleBizDto.getWhiteFigure());
			}
			// 金额
			mobileListRental(orderMemberBizDto, vo);
			// 按钮
			vo.setButtons(mobileButton(orderMemberBizDto, false, appVersion));
			// 查询加购信息
			vo.setPurchase(purchase(orderMemberBizDto));

			result.add(vo);
		}
		return result;
	}

	private PurchaseVo purchase(OrderMemberBizDto orderMemberBizDto) {
		PurchaseVo result = null;
		// 判断订单类型和状态
		if (OrderTypeEnum.EXCLUSIVEL.equals(orderMemberBizDto.getType())) {
			return result;
		}
		OrderSubscribeBizDto subscribeBizDto = (OrderSubscribeBizDto) orderMemberBizDto;
		if (subscribeBizDto.getCarId() == null) {
			// 无车辆id，不会有加购
			return result;
		}
		// 查询待支付加购信息
		List<OrderMileageDto> orderMileageDtos = orderMileageService
				.getOrderMileageList(subscribeBizDto.getOrderCode(), OrderMileagePayStatusEnum.WAIT);
		if (orderMileageDtos == null || orderMileageDtos.isEmpty()) {
			return result;
		}
		// 转换数据
		result = Convert.toPurchaseVo(orderMileageDtos.get(0));

		return result;
	}

	/**
	 * 订单列表租金-移动端
	 * 
	 * @param orderMemberBizDto
	 * @param vo
	 */
	private void mobileListRental(OrderMemberBizDto orderMemberBizDto, OrderMobileListVo vo) {
		// 判断订单类型
		if (OrderTypeEnum.EXCLUSIVEL.equals(orderMemberBizDto.getType())) {
			// 专属
			OrderExclusivelBizDto exclusivelBizDto = (OrderExclusivelBizDto) orderMemberBizDto;
			// 退租订单
			if (OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(exclusivelBizDto.getOrderStatus())
					|| OrderExclusivelStatusEnum.RENEGE_SETTLEMENT.equals(exclusivelBizDto.getOrderStatus())
					|| OrderExclusivelStatusEnum.RENEGE_REFUND.equals(exclusivelBizDto.getOrderStatus())
					|| OrderExclusivelStatusEnum.RENEGE_UNPAID.equals(exclusivelBizDto.getOrderStatus())
					|| OrderExclusivelStatusEnum.RENEGE_FINISH.equals(exclusivelBizDto.getOrderStatus())) {
				// 退租订单
				vo.setPayType(PaymentCostTypeEnum.RENEGE.getValue());
				vo.setRentalStr("");
				return;
			}
			if (OrderPaymentMethodEnum.INSTALLMENT.equals(exclusivelBizDto.getPaymentMethod())) {
				// 分期
				if (OrderExclusivelStatusEnum.TRADE_UNPAID.equals(exclusivelBizDto.getOrderStatus())
						|| OrderExclusivelStatusEnum.TRADE_UNAUDIT.equals(exclusivelBizDto.getOrderStatus())
						|| OrderExclusivelStatusEnum.TRADE_REJECTED.equals(exclusivelBizDto.getOrderStatus())
						|| OrderExclusivelStatusEnum.TRADE_REFUND.equals(exclusivelBizDto.getOrderStatus())
						|| OrderExclusivelStatusEnum.TRADE_FINISH.equals(exclusivelBizDto.getOrderStatus())) {
					// 待支付订单，无排期信息
					vo.setPayType(PaymentCostTypeEnum.SUBSCRIBE.getValue());
					vo.setRental(exclusivelBizDto.getRental().add(exclusivelBizDto.getDeposit()));
					vo.setRentalStr(vo.getRental().stripTrailingZeros().toPlainString() + "元");
					return;
				}

				// 查询未支付排期信息
				List<OrderScheduleDto> orderScheduleDtos = orderScheduleService
						.getOrderSchedule(exclusivelBizDto.getOrderCode(), OrderScheduleStatusEnum.NO);
				if (orderScheduleDtos == null) {
					// 不存在或已还完，显示全部金额信息（包含保证金）
					vo.setRental(exclusivelBizDto.getCartFee().add(exclusivelBizDto.getDeposit()));
					if (OrderExclusivelStatusEnum.RENEGE_FINISH.equals(exclusivelBizDto.getOrderStatus())) {
						vo.setRentalStr("");
					} else {
						vo.setRentalStr("待还0元");
					}
					return;
				}
				// 待还总额
				BigDecimal waitPayAmount = BigDecimal.ZERO;
				for (OrderScheduleDto orderScheduleDto : orderScheduleDtos) {
					// 待还
					waitPayAmount = waitPayAmount.add(orderScheduleDto.getPayable());
				}
				vo.setRental(waitPayAmount);
				vo.setRentalStr("待还 " + waitPayAmount.stripTrailingZeros().toPlainString() + "元");
			} else if (OrderPaymentMethodEnum.FULL.equals(exclusivelBizDto.getPaymentMethod())) {
				// 全款
				vo.setPayType(PaymentCostTypeEnum.SUBSCRIBE.getValue());
				vo.setRental(exclusivelBizDto.getCartFee().add(exclusivelBizDto.getDeposit()));
				vo.setRentalStr(vo.getRental().stripTrailingZeros().toPlainString() + "元");
			}
		} else if (OrderTypeEnum.SUBSCRIBE.equals(orderMemberBizDto.getType())) {
			// 订阅
			OrderSubscribeBizDto subscribeBizDto = (OrderSubscribeBizDto) orderMemberBizDto;
			if (OrderSubscribeStatusEnum.RETURN_UNPAID.equals(subscribeBizDto.getOrderStatus())) {
				// 待缴费，查询订单结算
				vo.setPayType(PaymentCostTypeEnum.SETTLEMENT.getValue());
				vo.setRental(subscribeBizDto.getSettlementFee());
				vo.setRentalStr(vo.getRental().stripTrailingZeros().toPlainString() + "元");
				return;
			}
			vo.setPayType(PaymentCostTypeEnum.SUBSCRIBE.getValue());
			vo.setRental(subscribeBizDto.getCartFee().add(subscribeBizDto.getDeposit()));
			vo.setRentalStr(vo.getRental().stripTrailingZeros().toPlainString() + "元");
		}
	}

	/**
	 * 订单按钮-移动端
	 *
	 * @param orderMemberBizDto
	 * @param isDetail
	 *            是否详情button
	 * @param appVersion
	 * @return
	 */
	private List<ButtonVo> mobileButton(OrderMemberBizDto orderMemberBizDto, boolean isDetail, String appVersion) {
		List<ButtonVo> result = new ArrayList<>();
//        Boolean tmp = false;
//		if (appVersion != null) {
//			String[] appNum = appVersion.split("[.]");
//			if (Integer.parseInt(appNum[0]) >= 3 && Integer.parseInt(appNum[1]) >= 1
//					&& Integer.parseInt(appNum[2]) >= 0) {
//				tmp = true;
//			}
//		} else {
//			tmp = true;
//		}

		// 判断订单类型
		if (OrderTypeEnum.EXCLUSIVEL.equals(orderMemberBizDto.getType())) {
			// 专属
			OrderExclusivelBizDto exclusivelBizDto = (OrderExclusivelBizDto) orderMemberBizDto;
			OrderExclusivelStatusEnum status = exclusivelBizDto.getOrderStatus();
			if (OrderExclusivelStatusEnum.TRADE_UNPAID.equals(status)) {
				// 待付款订单，取消、去支付
				if (!isDetail) {
					ButtonVo button = Convert.toButton(OrderButtonEnum.CANCEL);
					button.setName(button.getName().split("/")[0]);
					result.add(button);
				}
				if (OrderExclusivelTypeEnum.TYPE_ONE.equals(exclusivelBizDto.getExclusivelType())) {
					result.add(Convert.toButton(OrderButtonEnum.PAY));
				}
			} else if (OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(status)) {
				// 待提车
			} else if (OrderExclusivelStatusEnum.TRADE_USE.equals(status)) {
				// 用车中
				if (OrderPaymentMethodEnum.INSTALLMENT.equals(exclusivelBizDto.getPaymentMethod())
						&& OrderExclusivelTypeEnum.TYPE_ONE.equals(exclusivelBizDto.getExclusivelType())) {
					result.add(Convert.toButton(OrderButtonEnum.REPAYMENT));
				}
				result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
			} else if (OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(status)) {
				// 退租-待还车
				if (exclusivelBizDto.getCarId() != null) {
					// 存在车辆id代表已提车，是用车中发起退租（还款、合同）
					if (OrderPaymentMethodEnum.INSTALLMENT.equals(exclusivelBizDto.getPaymentMethod())) {
						// 分期
						result.add(Convert.toButton(OrderButtonEnum.REPAYMENT));
					}
					result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
				}
				result.add(Convert.toButton(OrderButtonEnum.RENEGE_CANCEL));
			} else if (OrderExclusivelStatusEnum.RENEGE_SETTLEMENT.equals(status)) {
				// 退租-财务结算中
				if (exclusivelBizDto.getCarId() != null) {
					// 存在车辆id代表已提车，是用车中发起退租（还款、合同）
					if (OrderPaymentMethodEnum.INSTALLMENT.equals(exclusivelBizDto.getPaymentMethod())) {
						// 分期
						result.add(Convert.toButton(OrderButtonEnum.REPAYMENT));
					}
					result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
				}
			} else if (OrderExclusivelStatusEnum.RENEGE_REFUND.equals(status)) {
				// 退租-解除协议确认
				if (exclusivelBizDto.getCarId() != null) {
					// 存在车辆id代表已提车，是用车中发起退租（还款、合同）
					if (OrderPaymentMethodEnum.INSTALLMENT.equals(exclusivelBizDto.getPaymentMethod())) {
						// 分期
						result.add(Convert.toButton(OrderButtonEnum.REPAYMENT));
					}
					result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
				}
				if (OrderRenegeCostTypeEnum.INCOME.equals(exclusivelBizDto.getRenege().getCostType())) {
					// 我司应收
					result.add(Convert.toButton(OrderButtonEnum.PAY));
				} else {
					// 我司应付
					result.add(Convert.toButton(OrderButtonEnum.RENEGE_CONFIRM));
				}
			} else if (OrderExclusivelStatusEnum.RENEGE_UNPAID.equals(status)) {
				// 退租-收/退款
				if (OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(exclusivelBizDto.getRenege().getBeforeOrderStatus())) {
					if (exclusivelBizDto.getRenege().getPayee() == null) {
						result.add(Convert.toButton(OrderButtonEnum.RENEGE_CANCEL));
					}
				} else {
					// 存在车辆id代表已提车，是用车中发起退租（还款、合同）
					if (OrderPaymentMethodEnum.INSTALLMENT.equals(exclusivelBizDto.getPaymentMethod())) {
						// 分期
						result.add(Convert.toButton(OrderButtonEnum.REPAYMENT));
					}
					result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
				}
				result.add(Convert.toButton(OrderButtonEnum.RENEGE_PAYEE));
			} else if (OrderExclusivelStatusEnum.RENEGE_FINISH.equals(status)) {
				// 退租-退租已完成
				if (exclusivelBizDto.getCarId() != null) {
					// 存在车辆id代表已提车，是用车中发起退租（还款、合同）
					if (OrderPaymentMethodEnum.INSTALLMENT.equals(exclusivelBizDto.getPaymentMethod())) {
						// 分期
						result.add(Convert.toButton(OrderButtonEnum.REPAYMENT));
					}
					result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
				}
			}
		} else if (OrderTypeEnum.SUBSCRIBE.equals(orderMemberBizDto.getType())) {
			// 订阅
			OrderSubscribeBizDto subscribeBizDto = (OrderSubscribeBizDto) orderMemberBizDto;
			OrderSubscribeStatusEnum status = subscribeBizDto.getOrderStatus();
			if (OrderSubscribeStatusEnum.TRADE_UNPAID.equals(status)) {
				// 待付款订单，取消、去支付
				if (!isDetail) {
					ButtonVo button = Convert.toButton(OrderButtonEnum.CANCEL);
					button.setName(button.getName().split("/")[0]);
					result.add(button);
				}
				result.add(Convert.toButton(OrderButtonEnum.PAY));
			} else if (OrderSubscribeStatusEnum.TRADE_UNDELIVERY.equals(status)) {
				// 待提车
			} else if (OrderSubscribeStatusEnum.TRADE_USE.equals(status)) {
				// 用车中
				result = reletButton(subscribeBizDto, result);
				result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
			} else if (OrderSubscribeStatusEnum.TRADE_UNUSE.equals(status)) {
				// 待用车
				result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
			} else if (OrderSubscribeStatusEnum.RETURN_UNINSPECTED.equals(status)) {
				// 待验车
				result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
			} else if (OrderSubscribeStatusEnum.RETURN_UNCONFIRM.equals(status)) {
				// 报告待确认
				if (!subscribeBizDto.getIsHaveSuborder()) {
					// 无续订，才显示验车报告
					result.add(Convert.toButton(OrderButtonEnum.REPORT));
				}
				result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
			} else if (OrderSubscribeStatusEnum.RETURN_INTERVENE.equals(status)) {
				// 待人工介入
//				if (!subscribeBizDto.getIsHaveSuborder()) {
//					// 无续订，才显示验车报告
//					result.add(Convert.toButton(OrderButtonEnum.REPORT));
//				}
//				result.add(Convert.toButton(OrderButtonEnum.CONTRACT));
			} else if (OrderSubscribeStatusEnum.RETURN_UNPAID.equals(status)) {
				// 待缴费
				result.add(Convert.toButton(OrderButtonEnum.REPORT));
				result.add(Convert.toButton(OrderButtonEnum.PAY));
			} else if (OrderSubscribeStatusEnum.RETURN_FINISH.equals(status)) {
				// 已完成
				if (!subscribeBizDto.getIsHaveSuborder()) {
					// 无续订，才显示验车报告
					result.add(Convert.toButton(OrderButtonEnum.REPORT));
				}
				result.add(Convert.toButton(OrderButtonEnum.CONTRACT));

			}
		}
		return result;
	}

	/**
	 * 加购、续订button逻辑
	 *
	 * @param subscribeBizDto
	 * @param result
	 * @return
	 */
	private List<ButtonVo> reletButton(OrderSubscribeBizDto subscribeBizDto, List<ButtonVo> result) {
		// 最迟还车时间
		LocalDateTime leaseExpire = LocalDateTime.parse(subscribeBizDto.getLeaseExpire().toString() + " 18:00:00",
				DateUtil.LOCAL_DATE_TIME);
		// 判断是否超时
		if (LocalDateTime.now().plusMinutes(10).isAfter(leaseExpire)) {
			// 超时
			return result;
		}
		// 查询里程
		CarDetailBizDto carDetailBizDto = carBizService.getCarDetail(subscribeBizDto.getCarId());
		Integer currentMileage = getCurrentMileage(carDetailBizDto.getVin(), false);
		if (currentMileage == null) {
			// 里程异常
			logger.error("[reletButton]查询里程信息异常");
			return result;
		}
		// 计算超里程数
		Integer beyondMileage = currentMileage - subscribeBizDto.getWarningMileage();
		if (beyondMileage < 0) {
			if (!subscribeBizDto.getIsHaveSuborder()) {
				// 已存在续订订单，则不可再次续订
				result.add(Convert.toButton(OrderButtonEnum.RENEW));
			}
			result.add(Convert.toButton(OrderButtonEnum.PURCHASED));
		} else if (beyondMileage >= 0 && beyondMileage <= 30) {
			result.add(Convert.toButton(OrderButtonEnum.PURCHASED));
		}
		return result;
	}

	/**
	 * 查询用户未完成订单信息（AIO）
	 * 
	 * @param user
	 *            用户
	 * @param deviceNum
	 *            大屏cpu号
	 * @return
	 * @throws Exception
	 */
	@Override
	public List<OrderAioVo> getAio(UserVo user, String deviceNum) throws Exception {
		List<OrderAioVo> result = null;
		boolean isBlack = false;
		// 查询是否黑名单用户
		BlacklistDto blacklistDto = blacklistService.getBlacklist(user.getPhone());
		if (blacklistDto != null) {
			isBlack = true;
		}
		// 获取所有用户正常订单
		List<OrderMemberBizDto> orderMemberBizDtos = orderBizService.getNormalOrderByUser(user.getUserId());
		if (orderMemberBizDtos == null || orderMemberBizDtos.isEmpty()) {
			if (isBlack) {
				throw new BizException(101, "抱歉！您未通过身份识别");
			}
			return result;
		}
		// 根据大屏cpu号查询绑定门店信息
		StoreBaseBizDto aioStore = storeBizService.getStoreBaseByCpu(deviceNum);
		result = new ArrayList<>();
		// 循环判断订单类型和状态
		for (OrderMemberBizDto orderMemberBizDto : orderMemberBizDtos) {
			OrderAioVo orderAioVo = null;
			if (OrderTypeEnum.EXCLUSIVEL.equals(orderMemberBizDto.getType())) {
				// 专属订单
				orderAioVo = getAioExclusivel((OrderExclusivelBizDto) orderMemberBizDto, aioStore, user, isBlack);
			} else if (OrderTypeEnum.SUBSCRIBE.equals(orderMemberBizDto.getType())) {
				// 订阅订单
				orderAioVo = getAioSubscribe((OrderSubscribeBizDto) orderMemberBizDto, aioStore, user, isBlack);
			}
			if (orderAioVo != null) {
				result.add(orderAioVo);
			}
		}
		if (result.isEmpty()) {
			result = null;
		}
		return result;
	}

	/**
	 * 专属订单
	 *
	 * @param orderBizDto
	 * @param user
	 * @param isBlack
	 * @param aioStore
	 * @return
	 * @throws Exception
	 */
	private OrderAioVo getAioExclusivel(OrderExclusivelBizDto orderBizDto, StoreBaseBizDto aioStore, UserVo user,
			boolean isBlack) throws Exception {
		OrderAioVo result = null;
		if (OrderExclusivelTypeEnum.TYPE_TWO.equals(orderBizDto.getExclusivelType())) {
			// 专属-订悦不显示
			return result;
		}

		// 判断订单状态
		if (OrderExclusivelStatusEnum.TRADE_FINISH.equals(orderBizDto.getOrderStatus())
				|| OrderExclusivelStatusEnum.RENEGE_FINISH.equals(orderBizDto.getOrderStatus())) {
			// 交易结束、退租已完成订单，不显示
			if (isBlack) {
				throw new BizException(101, "抱歉！您未通过身份识别");
			}
			return result;
		}
		if (isBlack && (OrderExclusivelStatusEnum.TRADE_UNPAID.equals(orderBizDto.getOrderStatus())
				|| OrderExclusivelStatusEnum.TRADE_UNDELIVERY.equals(orderBizDto.getOrderStatus()))) {
			throw new BizException(101, "抱歉！您未通过身份识别");
		}

		// 是否下单门店
		Boolean isPlaceStore = true;
		// 下单门店信息
		StoreBaseBizDto placeStore = null;
		// 判断是否是下单门店
		if (orderBizDto.getPlaceStoreId().equals(aioStore.getStoreId())) {
			// 是下单门店
			placeStore = aioStore;
		} else {
			// 待付款订单，且不是下单门店
			isPlaceStore = false;
			placeStore = storeBizService.getStoreBaseById(orderBizDto.getPlaceStoreId());
		}
		// 查询车型信息
		VehicleNameBizDto vehicleBizDto = vehicleBizService.getCarByModel(orderBizDto.getVehicleId());
		// 查询车辆信息
		CarDetailBizDto carDetailBizDto = null;
		if (orderBizDto.getCarId() != null) {
			carDetailBizDto = carBizService.getCarDetail(orderBizDto.getCarId());
		}
		// 已还期数，待还期数
		Integer repayPeriods = 0, waitPeriods = 0;
		boolean isOverdue = false;
		if (OrderPaymentMethodEnum.INSTALLMENT.equals(orderBizDto.getPaymentMethod())
				&& !OrderExclusivelStatusEnum.TRADE_UNPAID.equals(orderBizDto.getOrderStatus())) {
			// 分期且不是待付款状态查询排期
			List<OrderScheduleDto> orderScheduleDtos = orderScheduleService
					.getOrderSchedule(orderBizDto.getOrderCode());
			if (orderScheduleDtos != null && !orderScheduleDtos.isEmpty()) {
				boolean tmp = true;
				for (OrderScheduleDto orderScheduleDto : orderScheduleDtos) {
					if (OrderScheduleStatusEnum.ALREADY.equals(orderScheduleDto.getStatus())) {
						// 已还款
						repayPeriods += 1;
					} else {
						if (tmp && DateUtil.getDaysDiff(orderScheduleDto.getPayableDate(), LocalDate.now()) > 0) {
							// 是否已逾期
							isOverdue = true;
						}
						waitPeriods += 1;
						tmp = false;
					}
				}
			}
		}
		// 数据转换
		result = Convert.toOrderAioVo(orderBizDto, placeStore, user, vehicleBizDto, carDetailBizDto, isPlaceStore,
				repayPeriods, waitPeriods, isOverdue);
		result.setIsPlaceStore(isPlaceStore);
		// 按钮
		result.setButtons(aioButton(orderBizDto, isPlaceStore));

		return result;
	}

	/**
	 * 大屏订单详情按钮
	 * 
	 * @param orderBizDto
	 * @param isPlaceStore
	 * @return
	 */
	private List<ButtonVo> aioButton(OrderExclusivelBizDto orderBizDto, Boolean isPlaceStore) {
		List<ButtonVo> result = new ArrayList<>();
		// 专属
		if (OrderExclusivelStatusEnum.TRADE_UNPAID.equals(orderBizDto.getOrderStatus())) {
			// 待付款订单（重新签约、去支付）
			ButtonVo button = Convert.toButton(OrderButtonEnum.CANCEL);
			button.setName(button.getName().split("/")[1]);
			result.add(button);
			if (OrderExclusivelTypeEnum.TYPE_ONE.equals(orderBizDto.getExclusivelType())) {
				result.add(Convert.toButton(OrderButtonEnum.PAY));
			}
		} else if (OrderExclusivelStatusEnum.RENEGE_ACCEPTED.equals(orderBizDto.getOrderStatus())) {
			// 退租受理中（退租）
			if (orderBizDto.getCarId() != null && orderBizDto.getCarId() > 0 && isPlaceStore) {
				// 提车后才需要还车
				result.add(Convert.toButton(OrderButtonEnum.RENEGE));
			}
		} else {
			result = null;
		}

		return result;
	}

	/**
	 * 订阅订单
	 *
	 * @param orderBizDto
	 * @param user
	 * @param isBlack
	 * @param aioStore
	 * @return
	 * @throws Exception
	 */
	private OrderAioVo getAioSubscribe(OrderSubscribeBizDto orderBizDto, StoreBaseBizDto aioStore, UserVo user,
			boolean isBlack) throws Exception {
		OrderAioVo result = null;
		// 判断订单状态
		if (OrderSubscribeStatusEnum.TRADE_FINISH.equals(orderBizDto.getOrderStatus())
				|| OrderSubscribeStatusEnum.RETURN_FINISH.equals(orderBizDto.getOrderStatus())) {
			// 交易结束、已完成、退租已完成订单，不显示
			if (isBlack) {
				throw new BizException(101, "抱歉！您未通过身份识别");
			}
			return result;
		}
		if (isBlack && (OrderSubscribeStatusEnum.TRADE_UNPAID.equals(orderBizDto.getOrderStatus())
				|| OrderSubscribeStatusEnum.TRADE_UNDELIVERY.equals(orderBizDto.getOrderStatus()))) {
			throw new BizException(101, "抱歉！您未通过身份识别");
		}
		// 是否下单门店
		Boolean isPlaceStore = true;
		// 下单门店信息
		StoreBaseBizDto placeStore = null;
		// 判断是否是下单门店
		if (orderBizDto.getPlaceStoreId().equals(aioStore.getStoreId())) {
			// 是下单门店
			placeStore = aioStore;
		} else {
			// 待付款订单，且不是下单门店
			isPlaceStore = false;
			placeStore = storeBizService.getStoreBaseById(orderBizDto.getPlaceStoreId());
		}
		// 查询车型信息
		VehicleNameBizDto vehicleBizDto = vehicleBizService.getCarByModel(orderBizDto.getVehicleId());
		// 查询车辆信息
		CarDetailBizDto carDetailBizDto = null;
		if (orderBizDto.getCarId() != null) {
			carDetailBizDto = carBizService.getCarDetail(orderBizDto.getCarId());
		}
		// 查询订单车辆当前行驶里程
		Integer currentMileage = null;
		if (OrderSubscribeStatusEnum.TRADE_USE.equals(orderBizDto.getOrderStatus())) {
			// 用车中
			currentMileage = carDetailBizDto == null ? 0 : getCurrentMileage(carDetailBizDto.getVin(), true);
		} else {
			currentMileage = orderBizDto.getEndMileage();
		}
		// 数据转换
		result = Convert.toOrderAioVo(orderBizDto, placeStore, user, vehicleBizDto, isPlaceStore, currentMileage,
				carDetailBizDto);
		result.setIsPlaceStore(isPlaceStore);
		// 按钮
		result.setButtons(aioButton(orderBizDto, isPlaceStore));
		return result;
	}

	/**
	 * 大屏订单详情按钮
	 * 
	 * @param orderBizDto
	 * @param isPlaceStore
	 * @return
	 */
	private List<ButtonVo> aioButton(OrderSubscribeBizDto orderBizDto, Boolean isPlaceStore) {
		List<ButtonVo> result = new ArrayList<>();
		if (OrderSubscribeStatusEnum.TRADE_UNPAID.equals(orderBizDto.getOrderStatus())) {
			// 待付款订单（重新签约、去支付）
			ButtonVo button = Convert.toButton(OrderButtonEnum.CANCEL);
			button.setName(button.getName().split("/")[1]);
			result.add(button);
			if (isPlaceStore) {
				result.add(Convert.toButton(OrderButtonEnum.PAY));
			}
		} else if (OrderSubscribeStatusEnum.TRADE_USE.equals(orderBizDto.getOrderStatus())) {
			// 用车中（还车、退租、换车）
			if (isPlaceStore) {
				result.add(Convert.toButton(OrderButtonEnum.RETURN));
			}
			// result.add(Convert.toButton(OrderButtonEnum.RENEGE));
			// result.add(Convert.toButton(OrderButtonEnum.EXCHANGE));
		} else {
			result = null;
		}
		return result;
	}


	/**
	 * 查询用户专属里程订单详情
	 * 
	 * @param userId
	 *            用户id
	 * @param orderCode
	 *            订单号
	 * @return
	 * @throws Exception
	 */
	@Override
	public OrderExclusivelDetailsVo getExclusivelDetails(Integer userId, Long orderCode, String appVersion)
			throws Exception {
		OrderExclusivelDetailsVo result = null;
		// 根据订单号查询专属里程订单信息
		OrderExclusivelDetailsBizDto orderExclusivelDetailsBizDto = orderExclusivelBizService
				.getOrderExclusivelDetails(orderCode);
		if (orderExclusivelDetailsBizDto == null) {
			logger.error("[getExclusivelDetails]根据订单号(" + orderCode + ")查询订单异常，订单不存在");
			throw new BizException("查询失败，订单不存在");
		} else if (!orderExclusivelDetailsBizDto.getUserId().equals(userId)) {
			logger.error("[getExclusivelDetails]根据订单号(" + orderCode + ")、用户(" + userId + ")查询订单异常，订单用户信息不匹配");
			throw new BizException("查询失败，订单不存在");
		}
		// 数据转换
		result = Convert.toOrderExclusivelDetailsVo(orderExclusivelDetailsBizDto);
		// 状态说明
		result.setExplain(
				OrderUtil.statusExplain(OrderTypeEnum.EXCLUSIVEL, orderExclusivelDetailsBizDto.getOrderStatus()));
		// 查询门店信息
		StoreDto storeDto = storeService.getStoreById(orderExclusivelDetailsBizDto.getPlaceStoreId());
		// 门店名称
		result.setStoreName(storeDto.getShortName());
		// 查询车型信息
		VehicleNameBizDto vehicleBizDto = vehicleBizService.getCarByModel(orderExclusivelDetailsBizDto.getVehicleId());
		// 商品名称（ 品牌+车系+车型名称）
		result.setGoodsName(vehicleBizDto.getSubBrandName() + " " + vehicleBizDto.getSeriesName() + " "
				+ vehicleBizDto.getModelName());
		// 车辆图片
		result.setCarImg(vehicleBizDto.getWhiteFigure());
		// 查询车辆信息
		if (orderExclusivelDetailsBizDto.getCarId() != null) {
			CarDetailBizDto carDetailBizDto = carBizService.getCarDetail(orderExclusivelDetailsBizDto.getCarId());
			// 车牌号
			result.setLicencePlate(carDetailBizDto.getLicencePlate());
		}
		// 查询排期信息
		List<OrderScheduleDto> orderScheduleDtos = orderScheduleService
				.getOrderSchedule(orderExclusivelDetailsBizDto.getOrderCode());
		if (orderScheduleDtos == null || orderScheduleDtos.isEmpty()) {
			// 支付类型-订购
			result.setPayType(PaymentCostTypeEnum.SUBSCRIBE.getValue());
			// 应付金额（分期：本次支付金额(首付金额)+保证金 全款为合计, 全款：租车费+保证金）
			result.setPayableAmount(
					OrderPaymentMethodEnum.INSTALLMENT.equals(orderExclusivelDetailsBizDto.getPaymentMethod())
							? orderExclusivelDetailsBizDto.getRental().add(orderExclusivelDetailsBizDto.getDeposit())
							: orderExclusivelDetailsBizDto.getCartFee().add(orderExclusivelDetailsBizDto.getDeposit()));
		}

		if (OrderExclusivelStatusEnum.RENEGE_UNPAID.equals(orderExclusivelDetailsBizDto.getOrderStatus())) {
			result.setPayType(PaymentCostTypeEnum.RENEGE.getValue());
			// 查询退租信息
			OrderRenegeDto orderRenegeDto = orderRenegeService.getRenege(orderCode, OrderRenegeStatusEnum.RENEGE);
			result.setPayableAmount(orderRenegeDto.getCostAmount());
		}
		// 费用明细
		result.setCosts(Convert.toCostDetails(orderExclusivelDetailsBizDto, orderScheduleDtos));
		// button按钮
		result.setButtons(mobileButton(orderExclusivelDetailsBizDto, true, appVersion));

		return result;
	}

	/**
	 * 查询用户订阅里程订单详情
	 * 
	 * @param userId
	 *            用户id
	 * @param orderCode
	 *            订单号
	 * @return
	 * @throws Exception
	 */
	@Override
	public OrderSubscribeDetailsVo getSubscribeDetails(Integer userId, Long orderCode, String appVersion)
			throws Exception {
		OrderSubscribeDetailsVo result = null;
		// 根据订单号查询订阅里程订单信息
		OrderSubscribeDetailsBizDto orderSubscribeDetailsBizDto = orderSubscribeBizService
				.getOrderSubscribeDetails(orderCode);
		if (orderSubscribeDetailsBizDto == null) {
			logger.error("[getSubscribeDetails]根据订单号(" + orderCode + ")查询订单异常，订单不存在");
			throw new BizException("查询失败，订单不存在");
		} else if (!orderSubscribeDetailsBizDto.getUserId().equals(userId)) {
			logger.error("[getSubscribeDetails]根据订单号(" + orderCode + ")、用户(" + userId + ")查询订单异常，订单用户信息不匹配");
			throw new BizException("查询失败，订单不存在");
		}
		// 数据转换
		result = Convert.toOrderSubscribeDetailsVo(orderSubscribeDetailsBizDto);
		// 状态说明
		result.setExplain(
				OrderUtil.statusExplain(OrderTypeEnum.SUBSCRIBE, orderSubscribeDetailsBizDto.getOrderStatus()));
		// 查询门店信息
		StoreDto storeDto = storeService.getStoreById(orderSubscribeDetailsBizDto.getPlaceStoreId());
		// 门店名称
		result.setStoreName(storeDto.getShortName());
		// 查询车型信息
		VehicleNameBizDto vehicleBizDto = vehicleBizService.getCarByModel(orderSubscribeDetailsBizDto.getVehicleId());
		// 商品名称（ 品牌+车系+车型名称）
		result.setGoodsName(vehicleBizDto.getSubBrandName() + " " + vehicleBizDto.getSeriesName() + " "
				+ vehicleBizDto.getModelName());
		// 车辆图片
		result.setCarImg(vehicleBizDto.getWhiteFigure());
		// 查询车辆信息
		CarDetailBizDto carDetailBizDto = null;
		if (orderSubscribeDetailsBizDto.getCarId() != null
				&& !OrderSubscribeStatusEnum.TRADE_UNPAID.equals(orderSubscribeDetailsBizDto.getOrderStatus())) {
			carDetailBizDto = carBizService.getCarDetail(orderSubscribeDetailsBizDto.getCarId());
			// 车牌号
			result.setLicencePlate(carDetailBizDto.getLicencePlate());
		}
		// 使用情况
		result.setUsed(userUsed(orderSubscribeDetailsBizDto, carDetailBizDto));
		// 支付信息
		if (OrderSubscribeStatusEnum.TRADE_UNPAID.equals(orderSubscribeDetailsBizDto.getOrderStatus())) {
			// 待付款
			// 支付类型-订购
			result.setPayType(PaymentCostTypeEnum.SUBSCRIBE.getValue());
			// 合计
			result.setPayableAmount(
					orderSubscribeDetailsBizDto.getCartFee().add(orderSubscribeDetailsBizDto.getDeposit()));
		} else if (OrderSubscribeStatusEnum.RETURN_UNPAID.equals(orderSubscribeDetailsBizDto.getOrderStatus())) {
			// 待缴费
			// 支付类型-结算
			result.setPayType(PaymentCostTypeEnum.SETTLEMENT.getValue());
		}

		// 费用明细
		result.setCosts(Convert.toCostDetails(orderSubscribeDetailsBizDto));

		// button按钮
		result.setButtons(mobileButton(orderSubscribeDetailsBizDto, true, appVersion));
		
		if (OrderStatusConst.RETURN_SUBSCRIBE_STATUS.contains(orderSubscribeDetailsBizDto.getOrderStatus())) {
			List<DataVo> returnData = new ArrayList<>();
			// 检验结算信息
			List<CheckDto> checkDtos = checkService.getCheckByOrderCode(orderSubscribeDetailsBizDto.getOrderCode());
			if (checkDtos == null || checkDtos.isEmpty()) {
				return result;
			}
			for (CheckDto checkDto : checkDtos) {
				if (CarCheckTypeEnum.PDI.getValue() == checkDto.getType() && checkDto.getCheckTime() != null) {
					returnData.add(new DataVo("验车时间", DateUtil.formatTime(checkDto.getCheckTime())));
					break;
				}
			}
			if (orderSubscribeDetailsBizDto.getSettlement() != null
					&& orderSubscribeDetailsBizDto.getSettlement().getPayTime() != null) {
				returnData.add(new DataVo("缴费时间",
						DateUtil.formatTime(orderSubscribeDetailsBizDto.getSettlement().getPayTime())));
			}
			result.setSettlementDatas(returnData);
		}
		
		return result;
	}

	/**
	 * 用户使用情况
	 * 
	 * @param orderSubscribeDetailsBizDto
	 * @param carDetailBizDto
	 * @return
	 */
	@SuppressWarnings("unused")
	private UserUsedVo userUsed(OrderSubscribeDetailsBizDto orderSubscribeDetailsBizDto,
			CarDetailBizDto carDetailBizDto) {
		UserUsedVo used = new UserUsedVo();
		// 使用天数、使用里程数
		Integer usedDays = 0, usedMileage = 0;
		// 购买里程(基础里程+订阅里程+赠送里程+订阅里程（加购）)
		Integer payMileage = orderSubscribeDetailsBizDto.getBaseMileage()
				+ orderSubscribeDetailsBizDto.getPackageMileage() + orderSubscribeDetailsBizDto.getGiftMileage()
				+ orderSubscribeDetailsBizDto.getPurchaseMileage();
		if (OrderStatusConst.SUBSCRIBE_UNUSED_STATUS.contains(orderSubscribeDetailsBizDto.getOrderStatus())) {
			// 未用车订单，无使用情况
			return null;
		} else if (OrderStatusConst.SUBSCRIBE_USED_STATUS.contains(orderSubscribeDetailsBizDto.getOrderStatus())) {
			// 用车中订单，计算使用天数
			usedDays = (int) DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseInception(), LocalDate.now());
			// 查询订单车辆当前行驶里程
			Integer currentMileage = getCurrentMileage(carDetailBizDto.getVin(), true);
			if (DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseExpire(), LocalDate.now()) > 0) {
				// 超期
				used.setIsInvalid(true);
				// 计算超期前超出的未结算里程（订单到期时里程-预警里程）
				Integer beyondMileage = orderSubscribeDetailsBizDto.getEndMileage()
						- orderSubscribeDetailsBizDto.getWarningMileage();
				beyondMileage = beyondMileage > 0 ? beyondMileage : 0;
				// 计算超期后超出的里程数(当前里程-订单到期时里程)
				beyondMileage += currentMileage - orderSubscribeDetailsBizDto.getEndMileage();
				// 已超期订单，使用里程为购买里程+超出的里程数
				usedMileage = payMileage + beyondMileage;
			} else {
				// 未超期
				used.setIsInvalid(false);
				// 计算使用里程(当前里程-订单开始时里程-已结算超里程数)
				usedMileage = currentMileage - orderSubscribeDetailsBizDto.getStartMileage();
				if (orderSubscribeDetailsBizDto.getBeyondMileage() != null) {
					usedMileage -= orderSubscribeDetailsBizDto.getBeyondMileage();
				}
			}
		} else {
			// 已还车订单, 计算使用天数
			usedDays = (int) DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseInception(),
					orderSubscribeDetailsBizDto.getLeaseExpire());
			// 已还车订单，使用里程为购买里程
			usedMileage = payMileage;
		}

		// 用车时长
		used.setTransporTime(orderSubscribeDetailsBizDto.getTransportTime());
		// 订单天数
		used.setOrderDays((int) DateUtil.getDaysDiff(orderSubscribeDetailsBizDto.getLeaseInception(),
				orderSubscribeDetailsBizDto.getLeaseExpire()));
		// 使用天数
		used.setUsedDays(usedDays);
		// 时长说明
		used.setDurationExplain("(超时收费标准" + OrderConst.DAY_UNIT_PRICE + "元/天)");
		// 截止日
		used.setLeaseExpire(orderSubscribeDetailsBizDto.getLeaseExpire());
		// 购买里程数
		used.setPayMileage(payMileage);
		// 使用里程数
		used.setUsedMileage(usedMileage);
		// 里程数说明
		used.setMileageExplain("(超出里程部分，30公里内将按" + OrderConst.MILEAGE_UNIT_PRICE + "元/公里收取费用)");

		return used;
	}

	/**
	 * 获取车辆当前里程数
	 * 
	 * @param vin
	 *            车辆vin
	 * @param isThrow
	 *            是否抛出异常
	 * @return
	 */
	private Integer getCurrentMileage(String vin, boolean isThrow) {
		Integer result = null;
		try {
			// 车辆里程
			result = iovCarService.getCurrentMileage(vin);
		} catch (Exception e) {
			logger.error("[getCurrentMileage]获取车辆当前里程数异常：", e);
		}
		if (result == null && isThrow) {
			logger.error("[getCurrentMileage]查询车辆({})行驶里程异常", vin);
			throw new BizException("查询车辆行驶里程异常");
		}
		return result;
	}

	/**
	 * 检验是否可以加购
	 * 
	 * @param orderCode
	 *            订单号
	 * @return
	 */
	@Override
	public ReletVerifyVo getVerifyPurchase(Long orderCode) {
		ReletVerifyVo result = new ReletVerifyVo();
		// 查询是否存在未支付的加购里程信息
		List<OrderMileageDto> orderPurchases = orderMileageService.getOrderMileageList(orderCode,
				OrderMileagePayStatusEnum.WAIT);
		if (orderPurchases == null || orderPurchases.isEmpty()) {
			// 不存在
			result.can();
		} else {
			// 存在
			result.cannot("您有待付款的加购里程包订单", orderPurchases.get(0).getOrderCode());
		}

		return result;
	}

	/**
	 * 检验是否可以续订
	 * 
	 * @param orderCode
	 *            订单号
	 * @return
	 */
	@Override
	public ReletVerifyVo getVerifyRenew(Long orderCode) {
		ReletVerifyVo result = new ReletVerifyVo();
		// 查询是否存在未支付的续订信息
		OrderSubscribeDto renew = orderSubscribeService.getOrderSubscribeByParent(orderCode,
				OrderSubscribeStatusEnum.TRADE_UNPAID);
		if (renew == null) {
			// 不存在
			result.can();
		} else {
			// 存在
			result.cannot("您有一条待付款的续订订单", renew.getOrderCode());
		}

		return result;
	}
}
